package request

import (
	"github.com/gin-gonic/gin"
	"github.com/pkg/errors"
	"mime/multipart"
	"strconv"
	"trpg-common/dto"
	"trpg-common/logger"
)

func GetUserFromGinContext(c *gin.Context) dto.UserInfo {
	value, exists := c.Get("user")
	if !exists {
		logger.Logger.Panicf("%v", errors.Wrap(errors.New("no user in context"), "no user in context"))
	}
	info, ok := value.(dto.UserInfo)
	if !ok {
		logger.Logger.Panicf("%v", errors.Wrap(errors.New("no user in context"), "no user in context"))
	}
	return info
}

func GetStructFromGinContext(c *gin.Context, value interface{}) {
	err := c.ShouldBind(value)
	if err != nil {
		logger.Logger.Panicf("%+v", errors.Wrap(err, "error in getting param from request"))
	}
}

func GetStringFromPath(c *gin.Context, key string) string {
	return c.Param(key)
}

func GetIntFromPath(c *gin.Context, key string) int64 {
	param := c.Param(key)
	res, err := strconv.ParseInt(param, 10, 64)
	if err != nil {
		logger.Logger.Panicf("%+v", errors.Wrap(err, "error in getting param from request"))
	}
	return res
}

func GetFloatFromPath(c *gin.Context, key string) float64 {
	param := c.Param(key)
	res, err := strconv.ParseFloat(param, 64)
	if err != nil {
		logger.Logger.Panicf("%+v", errors.Wrap(err, "error in getting param from request"))
	}
	return res
}

func GetBoolFromPath(c *gin.Context, key string) bool {
	param := c.Param(key)
	res, err := strconv.ParseBool(param)
	if err != nil {
		logger.Logger.Panicf("%+v", errors.Wrap(err, "error in getting param from request"))
	}
	return res
}

func GetStringFromQuery(c *gin.Context, key string) string {
	return c.Query(key)
}

func GetIntFromQuery(c *gin.Context, key string) int64 {
	param := c.Query(key)
	res, err := strconv.ParseInt(param, 10, 64)
	if err != nil {
		logger.Logger.Panicf("%+v", errors.Wrap(err, "error in getting param from request"))
	}
	return res
}

func GetFloatFromQuery(c *gin.Context, key string) float64 {
	param := c.Query(key)
	res, err := strconv.ParseFloat(param, 64)
	if err != nil {
		logger.Logger.Panicf("%+v", errors.Wrap(err, "error in getting param from request"))
	}
	return res
}

func GetBoolFromQuery(c *gin.Context, key string) bool {
	param := c.Query(key)
	res, err := strconv.ParseBool(param)
	if err != nil {
		logger.Logger.Panicf("%+v", errors.Wrap(err, "error in getting param from request"))
	}
	return res
}

func GetFileFromForm(c *gin.Context, key string) *multipart.FileHeader {
	file, err := c.FormFile(key)
	if err != nil {
		logger.Logger.Panicf("%+v", errors.Wrap(err, "error in getting param from request"))
	}
	return file
}
